////////////////////////////////////////////////////////////////////////////////
/// @file    sdio.c
/// @author  AE TEAM
/// @brief   THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
////////////////////////////////////////////////////////////////////////////////
/// @attention
///
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////
// Define to prevent recursive inclusion
#define _SDIO_C_

// Files includes

#include "SDIO.h"
#include "uart.h"
#include "sdio_sdcard.h"
#include "delay.h"
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup MM32_Example_Layer
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup SDIO
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup SDIO_Exported_Constants
/// @{

extern u32 SystemCoreClock;
////////////////////////////////////////////////////////////////////////////////
/// @brief  SDIO GPIO remap config.
/// @param  None.
/// @retval  0.
////////////////////////////////////////////////////////////////////////////////
void SDIO_PIN_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

//    PC8     SDCard_DAT0
//    PC9     SDCard_DAT1
//    PC10    SDCard_DAT2
//    PC11    SDCard_DAT3
//    PC12    SDCard_CLK
//    PD2     SDCard_CMD

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC | RCC_AHBENR_GPIOD, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG, ENABLE);                         //enable sys_cfg clk

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_12);                       //PD2   SDIO_CMD
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_12);                       //PC8   SDIO_D0
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_12);                       //PC9   SDIO_D1
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_12);                      //PC10  SDIO_D2
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_12);                      //PC11  SDIO_D3
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_12);                      //PC12  SDIO_CLK

    //set PD2 AF SDCard_CMD
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    //PC8 AF SDCard_DAT0, PC9 AF SDCard_DAT1, PC10 AF SDCard_DAT2,
    //PC11 AF SDCard_DAT3, PC12 AF SDCard_CLK
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_8  | \
                                    GPIO_Pin_9  | \
                                    GPIO_Pin_10 | \
                                    GPIO_Pin_11 | \
                                    GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  SDIO Detect Pin GPIO configuration
/// @param  None
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void SDIO_Detect_Pin_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
    //set PC7 AS SDIO_DET
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief  SDIO Card PlugIn Status Check
/// @param  None
/// @retval Bool.
////////////////////////////////////////////////////////////////////////////////
bool SDIO_Card_PlugIn_Status_Check(void)
{
    bool result;

    result = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);
    DELAY_Ms(10);
    if(result == GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6))
        return result;
    return RESET;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  SDIO initialize.
/// @param  None.
/// @retval  0.
////////////////////////////////////////////////////////////////////////////////
void SDIO_ConfigInit(void)
{
    u8 clk;
    SDIO_InitTypeDef SDIO_InitStruct;

    SDIO_PIN_GPIO_Config();
    SDIO_Detect_Pin_Config();

    RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE);
    SDIO_DeInit();
    RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, DISABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE);

    clk = (SystemCoreClock / 1600000 - 1);
    SDIO_ClockSet(clk);
    SDIO_StructInit(&SDIO_InitStruct);


    SDIO_InitStruct.SDIO_OPMSel = SDIO_MMC_CTRL_OPMSel;
    SDIO_InitStruct.SDIO_SelPTSM = SDIO_MMC_CTRL_SelSM;
    SDIO_InitStruct.SDIO_DATWT = SDIO_MMC_CTRL_DATWT;
    SDIO_Init(&SDIO_InitStruct);

    SDIO_CRCConfig(SDIO_MMC_CRCCTL_CMD_CRCEN | SDIO_MMC_CRCCTL_DAT_CRCEN, ENABLE);
}

/// @}

/// @}

/// @}

